﻿using System;
using System.IO;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using AvaloniaEdit;
using AvaloniaEdit.CodeCompletion;
using AvaloniaEdit.Document;
using AvaloniaEdit.Folding;
using AvaloniaEdit.TextMate;
using LuckyCoding.Edit;
using TextMateSharp.Grammars;

namespace LuckyCoding.FileView;

public partial class EditFileView : UserControl
{
    public string FilePath { get; set; }
    private string? Extension { get; set; }
    private OverloadInsightWindow? InsightWindow { get; set; }
    private CompletionWindow? TextEditCompletionWindow { get; set; }
    private CompletionWindow? CompletionWindow { get; set; }
    private RegistryOptions RegistryOptions { get; }
    private TextMate.Installation TextMateInstallation { get;  }
    private FoldingManager FoldingManager { get; set; }
    private XmlFoldingStrategy FoldingStrategy { get; set; } = new XmlFoldingStrategy();

    public EditFileView(string path, string code)
    {
        InitializeComponent();
        Extension = Path.GetExtension(path);
        FilePath = path;
        Editor.FontFamily = Avalonia.Media.FontFamily.Parse("Cascadia Code,Consolas,Menlo,Monospace");
        Editor.TextArea.TextEntered += TextEntered;
        Editor.TextArea.TextEntering += TextEntering;
        RegistryOptions = new RegistryOptions(ThemeName.Dark);
        TextMateInstallation = Editor.InstallTextMate(RegistryOptions);
        Editor.Document = new TextDocument(code);
        TextMateInstallation.SetGrammar(
            RegistryOptions.GetScopeByLanguageId(RegistryOptions.GetLanguageByExtension(Extension).Id));
        Editor.TextChanged += EditorTextChange;
        FoldingManager = FoldingManager.Install(Editor.TextArea);
        FoldingStrategy.UpdateFoldings(FoldingManager, Editor.Document);
    }

    private void EditorTextChange(object? sender, EventArgs e)
    {
        FoldingStrategy.UpdateFoldings(FoldingManager, Editor.Document);
    }

    private void InitializeComponent()
    {
        AvaloniaXamlLoader.Load(this);
        Editor = this.FindControl<TextEditor>("Editor");
    }

    #region Editor

    private void TextEntered(object? sender, TextInputEventArgs e)
    {
        if (e.Text == ".")
        {
            CompletionWindow = new CompletionWindow(Editor.TextArea);
            CompletionWindow.Closed += (_, _) => CompletionWindow = null;
            var data = CompletionWindow.CompletionList.CompletionData;
            data.Add(new CompletionData("Item1"));
            data.Add(new CompletionData("Item2"));
            data.Add(new CompletionData("Item3"));
            data.Add(new CompletionData("Item4"));
            data.Add(new CompletionData("Item5"));
            data.Add(new CompletionData("Item6"));
            data.Add(new CompletionData("Item7"));
            data.Add(new CompletionData("Item8"));
            data.Add(new CompletionData("Item9"));
            data.Add(new CompletionData("Item10"));
            data.Add(new CompletionData("Item11"));
            data.Add(new CompletionData("Item12"));
            data.Add(new CompletionData("Item13"));
            CompletionWindow.Show();
        }
        else if (e.Text == "(")
        {
            InsightWindow = new OverloadInsightWindow(Editor.TextArea);
            InsightWindow.Closed += (_, _) => InsightWindow = null;
            InsightWindow.Provider = new OverloadProvider(new[]
            {
                ("Method1(int, string)", "Method1 description"),
                ("Method2(int)", "Method2 description"),
                ("Method3(string)", "Method3 description"),
            });
            InsightWindow.Show();
        }
        else if (e.Text == "{")
        {
        }
    }

    private void TextEntering(object? sender, TextInputEventArgs e)
    {
        if (e.Text!.Length > 0 && TextEditCompletionWindow != null)
        {
            if (!char.IsLetterOrDigit(e.Text[0]))
            {
                //每当在完成窗口打开时键入非字母时，插入当前选定的元素。
                TextEditCompletionWindow.CompletionList.RequestInsertion(e);
            }
        }

        InsightWindow?.Hide();

        // 不要设置 e.Handled=true。我们仍然希望插入键入的字符。
    }

    #endregion


    public void Change(string code, string path)
    {
        Editor.Text = code;
        FilePath = path;
        var lang = Path.GetExtension(path);
        if(lang == Extension)return;
        Extension = lang;
        TextMateInstallation.SetGrammar(
            RegistryOptions.GetScopeByLanguageId(RegistryOptions.GetLanguageByExtension(lang).Id));
    }


    
}